using System;
using System.Diagnostics;
using System.Linq;
using System.Collections.Generic;
using Common.Unity.Extensions.PropertyMapper.Policies;
using Microsoft.Practices.ObjectBuilder2;

namespace Common.Unity.Extensions.PropertyMapper
{
	public abstract class PropertyMappingStrategyBase : BuilderStrategy
	{
		readonly Stack<IDisposable> managers = new Stack<IDisposable>();

		public override void PreBuildUp(IBuilderContext context)
		{
			IPropertyMappingContextPolicy contextPolicy = context.Policies.Get<IPropertyMappingContextPolicy>( null, true );
			if ( contextPolicy != null )
			{
				IPropertySetterPolicy setter = context.GetEnsuredPolicy<IPropertySetterPolicy, PropertySetterPolicy>();
				DynamicPropertySetterManager manager =
					new DynamicPropertySetterManager( contextPolicy.Context, setter, ResolvePolicies( context, contextPolicy.Context.Key ).ToArray() );
				managers.Push( manager );
			}
		}

		public override void PostBuildUp(IBuilderContext context)
		{
			IPropertyMappingContextPolicy contextPolicy = context.Policies.Get<IPropertyMappingContextPolicy>( null );
			if ( contextPolicy != null )
			{
				managers.Pop().Dispose();
			}
		}

		protected abstract IEnumerable<IPropertyMappingPolicy> ResolvePolicies( IBuilderContext context,
		                                                                                PropertyMappingKey key );
	}
}